#include <iostream>

using namespace std;

// getmem 和 getA1 是等价的，都是开辟一个空间，拷贝值，不同的是getmem返回时指针，getA1返回的是值
char* getmem(int num) {
	char *p = NULL;
	p = (char*)malloc(num);
	return p;
}
// 通过这种方式会经历一次拷贝操作，如果是一个结构体或者数组之类的，会造成内存的浪费
int getA1() {
	int a = 11;
	return a;
}

// ----------------------------

// getmem 和 getA2 是等价的，通过指针的方式来改变值
char* getmem2(char **pp, int num) {
	char *p = NULL;
	p = (char*)malloc(num);
	*pp = p;
	return 0;
}
// 通过指针的方式，传递a的指针，然后对指针的进行赋值
int getA2(int *a) {
	*a = 10;
	return *a;
}

// ----------------------------

// int &temp = a，因为a是局部变量，当返回以后，用一个值去接受，会发生一个拷贝，将a的值赋值到其他变量
// 用一个引用去接收a，因为a在返回以后会被销毁，外部接收的变量同样也会被销毁，因此会引发异常
int& getA3(){
	int a = 12;
	// 这里会存在一个警告，告诉我们不要将局部变量作为引用返回出去
	return a;
}

// 返回一个静态局部变量的引用
int& getA4(){
	static int a = 18;
	return a;
}


int main(int argc, char *argv[]) {

	int a = 0;
	char *pp = NULL;

	a = getA1();
	pp = getmem(10);

	cout << a << endl;
	cout << pp << "--" << endl;
#if 0
	int main_a = 0;
	main_a = getA3();
	cout << main_a << endl;
	int& main_a_re = getA3();
	cout << main_a_re << endl;
#endif

	int main_a = getA4();
	cout << main_a << endl;
	// 引用如果当函数的返回值，函数可以当做左值
	// 引用当左值：表示将右边的值赋值给引用对应的内存
	// 引用到右值：表示将引用赋值给一个引用类型变量
	getA4() = 40;
	main_a = getA4();
	cout << main_a << endl;

	return 0;
}
